﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Collections;
using System.Net;
using System.IO;
using SocketLib.Buffers;
using System.Threading;

namespace SocketLib
{
    public class Server2
    {

        private byte[] buff = new byte[1024 * 10]; //缓冲区64K

        CircularBuffer cb = new CircularBuffer();
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public ConnectionList Connections = new ConnectionList();


        #region 事件委托
        public delegate void CallbackDelegate(object sender, CallbackEventArgs e);
        public event CallbackDelegate Callback_EventHandler;

        public delegate void Accept_Delegate(object sender, Accept_EventArgs e);
        public event Accept_Delegate Accept_EventHandler;

        public delegate void Closed_Delegate(object sender, Closed_EventArgs e);
        public event Closed_Delegate Closed_EventHandler;


        public class CallbackEventArgs : EventArgs
        {
            //public IPMPack pack { get; set; }
            public byte[] buffer { get; set; }

        }

        public class Accept_EventArgs : EventArgs
        {
            public string ip { get; set; }
        }

        public class Closed_EventArgs : EventArgs
        {
            public Socket socket { get; set; }
        }

        #endregion

        public void Start()
        {
            
            socket.Bind(new IPEndPoint(Dns.GetHostAddresses(Dns.GetHostName())[1], 3451));
            socket.Listen(10);
            //socket.BeginAccept(new AsyncCallback(AcceptCallback), socket);

            ThreadPool.QueueUserWorkItem(new WaitCallback(Accept));

            ThreadPool.QueueUserWorkItem(new WaitCallback(AnalysisbufferPool));

        }


        public void AcceptCallback(IAsyncResult ar)
        {

            Socket s = (Socket)ar.AsyncState;
            Socket TcpSocket = s.EndAccept(ar);

            Connections.Add(new Connection(TcpSocket));


            if (Accept_EventHandler != null)
            {
                Accept_EventArgs args = new Accept_EventArgs();
                args.ip = TcpSocket.RemoteEndPoint.ToString();

                Accept_EventHandler(this, args);
            }


            TcpSocket.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(Read_Callback2), TcpSocket);

            //TcpSocket.RemoteEndPoint.ToString() + "建立连接";

        }


        public void Accept(object o)
        {
            while (true)
            {
                Thread.Sleep(500);
                socket.BeginAccept(new AsyncCallback(AcceptCallback), socket);
            }
        }


        private void Disconnect(Socket sc)
        {
            if (Closed_EventHandler != null)
            {
                Closed_EventArgs args = new Closed_EventArgs();
                args.socket = sc;
                Closed_EventHandler(this, args);
            }
        }


        public void Read_Callback2(IAsyncResult ar)
        {


            Socket client = (Socket)ar.AsyncState;
            try
            {

                int revCount = client.EndReceive(ar);

                //int a = client.Available;

                if (revCount > 0)
                {
                    Byte[] a = new Byte[revCount];
                    Buffer.BlockCopy(buff, 0, a, 0, revCount);
                    cb.Write(a, 0, a.Length);    

                }
                client.BeginReceive(buff, 0, buff.Length, SocketFlags.None, new AsyncCallback(Read_Callback2), client);

            }
            catch (SocketException ex)
            {
                if (ex.ErrorCode == 10054)
                {
                    //throw new SocketLib.ex.ClientClosedException(ex.Message);
                    Disconnect(client);

                }
            }
            finally
            {

            }

        }


        public void AnalysisbufferPool(object o)
        {

            while (true)
            {
                //取出包的大小
                Thread.Sleep(500);
                byte[] b1 = cb.Read(0, 4);

                if (b1 == null)
                    continue;

                int len = BitConverter.ToInt32(b1, 0);

                byte[] data = cb.Read(0, len - 4);

                byte[] byteDate = new byte[len + 4];
                Buffer.BlockCopy(b1, 0, byteDate, 0, 4);

                Buffer.BlockCopy(data, 0, byteDate, 4, data.Length);


                //把完整的包发过去处理
                if (Callback_EventHandler != null)
                {
                    CallbackEventArgs args = new CallbackEventArgs();
                    args.buffer = byteDate;
                    Callback_EventHandler(this, args);
                }


            }
        }



        public void Send(string msg)
        {





            byte[] data = Encoding.Default.GetBytes(msg);
            IPMPack pack = new IPMPack();
            pack.PackType = 1;
            //pack.PackSize = data.Length;
            pack.PackNo = 10000;
            pack.Data = data;

            byte[] sendBuff = pack.Packed();


            foreach (Connection cl in Connections)
            {
				if (cl.ClientSocket.Connected)
				{
					cl.ClientSocket.Send(sendBuff);
				}
               
            }

        }


    }

}
